home *** CD-ROM | disk | FTP | other *** search
- //
- // This is a patch for the Inventor 2.0 Text2 node, which will
- // core dump when given an character code in the range 128-255.
- //
- // To apply this patch, compile this file into a .o and then link
- // the .o before -lInventor. You will also need to link with -lFL,
- // the internal, undocumented font library that Inventor uses (sorry,
- // no, a public, released, documented version is NOT available).
- // The linker may give a warning about
- // multiply defined symbols. This is normal and expected.
- //
-
- #include <GL/gl.h>
- #include <Inventor/SbBox.h>
- #include <Inventor/SoPickedPoint.h>
- #include <Inventor/actions/SoCallbackAction.h>
- #include <Inventor/actions/SoGLRenderAction.h>
- #include <Inventor/actions/SoRayPickAction.h>
- #include <Inventor/bundles/SoMaterialBundle.h>
- #include <Inventor/caches/SoGLRenderCache.h>
- #include <Inventor/details/SoTextDetail.h>
- #include <Inventor/elements/SoCacheElement.h>
- #include <Inventor/elements/SoFontNameElement.h>
- #include <Inventor/elements/SoFontSizeElement.h>
- #include <Inventor/elements/SoGLCacheContextElement.h>
- #include <Inventor/elements/SoGLTextureImageElement.h>
- #include <Inventor/elements/SoLightModelElement.h>
- #include <Inventor/elements/SoMaterialBindingElement.h>
- #include <Inventor/elements/SoModelMatrixElement.h>
- #include <Inventor/elements/SoProjectionMatrixElement.h>
- #include <Inventor/elements/SoViewingMatrixElement.h>
- #include <Inventor/elements/SoViewportRegionElement.h>
- #include <Inventor/errors/SoDebugError.h>
- #include <Inventor/misc/SoState.h>
- #include <Inventor/nodes/SoText2.h>
-
- #include <math.h>
-
- // Internal font library stuff from the unshipped flclient.h.
- // DO NOT TRY TO USE THIS!
- class SoFontOutline;
- typedef GLint FLfontNumber;
- typedef struct __FLcontextRec *FLcontext;
- #define FL_HINT_AABITMAPFONTS 1 /* bound to font */
- #define FL_HINT_CHARSPACING 2 /* bound to font */
- #define FL_HINT_FONTTYPE 3 /* bound to font */
- #define FL_HINT_MAXAASIZE 4 /* bound to font */
- #define FL_HINT_MINOUTLINESIZE 5 /* bound to font */
- #define FL_HINT_ROUNDADVANCE 6 /* bound to font */
- #define FL_HINT_SCALETHRESH 7 /* bound to font */
- #define FL_HINT_TOLERANCE 8 /* bound to font */
-
- extern "C" {
-
- FLfontNumber flCreateFont(
- const GLubyte * /* fontName */,
- GLfloat [2][2] /* mat */,
- GLint /* charNameCount */,
- GLubyte ** /* charNameVector */
- );
- void flSetHint(
- GLuint /* hint */,
- GLfloat /* hintValue */
- );
- GLboolean flMakeCurrentFont(
- FLfontNumber /* fn */
- );
-
- typedef struct FLbitmap {
- GLsizei width;
- GLsizei height;
- GLfloat xorig;
- GLfloat yorig;
- GLfloat xmove;
- GLfloat ymove;
- GLubyte *bitmap;
- } FLbitmap;
- };
-
- // An internal class that makes life easier:
- // This very specialized cache class is used to cache bitmaps and GL
- // display lists containing bitmaps. It is strange because it doesn't
- // use the normal list of elements used to determine validity, etc,
- // and knows exactly which elements it depends on.
-
- class SoBitmapFontCache : public SoGLRenderCache
- {
- public:
- // Return a font (either a new one or an old one) that is valid
- // for the given state.
- static SoBitmapFontCache * getFont(SoState *state);
-
- // Checks to see if this font is valid
- SbBool isValid(SoState *state) const;
-
- // Use this when rendering to decide if this cache is valid (it
- // checks the GL cache context in addition to other elements)
- SbBool isRenderValid(SoState *state) const;
-
- // Set up for GL rendering:
- void setupToRender(SoState *state);
-
- // Returns the amount the current raster position will be advanced
- // after drawing the given character.
- SbVec3f getCharOffset(char c);
-
- // Get the pixel-space bounding box of a given character.
- void getCharBbox(char c, SbBox3f &box);
-
- // Gets the width (in pixels) of the given string
- float getWidth(const SbString &str);
-
- // Gets the height of the font, in pixels
- float getHeight();
-
- // Draws the given string
- void drawString(const SbString &string);
-
- // Draws the given character (using GL)
- void drawCharacter(char c);
-
- protected:
- // Free up display lists before being deleted
- virtual void destroy(SoState *state);
-
- private:
- // Constructor.
- SoBitmapFontCache(SoState *state);
-
- // Destructor
- virtual ~SoBitmapFontCache();
-
- // Returns TRUE if this font cache has a display list for the
- // given character. It will try to build a display list, if it
- // can.
- SbBool hasDisplayList(const char c);
-
- // Renders an entire string by using the GL callList() function.
- void callLists(const SbString &string);
-
- const FLbitmap *getBitmap(unsigned char c);
-
- // Static list of all fonts. OPTIMIZATION: If there turn out to
- // be applications that use lots of fonts, we could change this
- // list into a dictionary keyed off the font name.
- static SbPList *fonts;
-
- int numChars; // Number of characters in this font
-
- GLuint listBase; // Start of GL display lists. Will be 0 if
- // they haven't been allocated yet.
- SbBool *listFlags;// Flag for each character-- have we built
- // GL display list yet?
- FLbitmap **bitmaps; // Cached bitmaps for each character. NULL
- // if bitmap hasn't been fetched yet.
- int cacheContext; // Cache context
-
- // This flag will be true if there is another cache open (if
- // building GL display lists for render caching, that means we
- // can't also build display lists).
- SbBool otherOpen;
-
- // And some font library stuff:
- static FLcontext flContext;
- FLfontNumber fontId;
- };
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Description:
- // Construct a bitmap font cache, given the state and a dummy
- // (empty) list of overridden elements (needed only to pass to the
- // SoCache constructor).
- //
- // Use: internal, private
-
- SoBitmapFontCache::SoBitmapFontCache(SoState *state) : SoGLRenderCache(state)
- //
- ////////////////////////////////////////////////////////////////////////
- {
- ref();
-
- // Tell base class to ignore overridden elements in isValid
- // check-- this is safe because the only relevant elements are
- // guaranteed to already be on the elementsUsed list, so we're
- // sure to detect changes to them.
- setCompareOverridden(FALSE);
-
- cacheContext = -1;
-
- // Grab all the stuff we'll need to determine our validity from
- // the state.
- SbName fontName = SoFontNameElement::get(state);
- addElement(state->getConstElement(
- SoFontNameElement::getClassStackIndex()));
- if (fontName == SoFontNameElement::getDefault()) {
- fontName = SbName("Utopia-Regular");
- }
- const SbViewportRegion &vpr = SoViewportRegionElement::get(state);
- addElement(state->getConstElement(
- SoViewportRegionElement::getClassStackIndex()));
- float fontSize = SoFontSizeElement::get(state) * vpr.getPixelsPerPoint();
- addElement(state->getConstElement(
- SoFontSizeElement::getClassStackIndex()));
-
- // Initialize everything
- GLfloat m[2][2];
- m[0][0] = m[1][1] = fontSize;
- m[0][1] = m[1][0] = 0.0;
- fontId = flCreateFont((const GLubyte *)fontName.getString(), m, 0, NULL);
-
- if (fontId == 0) {
- // Try Utopia-Regular, unless we just did!
- if (fontName != SbName("Utopia-Regular")) {
- #ifdef DEBUG
- SoDebugError::post("SoText2::getFont",
- "Couldn't find font %s, replacing with Utopia-Regular",
- fontName.getString());
- #endif
- fontId = flCreateFont((const GLubyte *)"Utopia-Regular",
- m, 0, NULL);
- }
- if (fontId == 0) {
- #ifdef DEBUG
- SoDebugError::post("SoText3::getFont",
- "Couldn't find font Utopia-Regular!");
- #endif
- numChars = 0;
- return;
- }
- }
- flMakeCurrentFont(fontId);
-
- numChars = 256;
- listBase = 0;
- listFlags = new SbBool[numChars];
- bitmaps = new FLbitmap*[numChars];
- for (int i = 0; i < numChars; i++) {
- listFlags[i] = FALSE;
- bitmaps[i] = NULL;
- }
-
- fonts->append(this);
- }
-